﻿#ifndef __SS_LIST_H__
#define __SS_LIST_H__
#include "../memory/ssDoublyList.h"

namespace StarSeeker
{

template<typename T>
class ssList
{
public:
	class Iterator
	{
		friend class ssList;
	public:
		Iterator():m_pNode(0)
		{
		}
		Iterator(const Iterator& i):m_pNode(i.m_pNode)
		{
		}
		Iterator(typename ssDoublyList<sizeof(T)>::Node_s* p):m_pNode(p)
		{
		}
		void operator= (const Iterator& i)
		{
			m_pNode = i.m_pNode;
		}
		void operator++ ()
		{
			if(m_pNode)
				m_pNode = m_pNode->Next();
		}
		void operator-- ()
		{
			if (m_pNode)
				m_pNode = m_pNode->Previous();
		}
		bool operator== (const Iterator& i)
		{
			return m_pNode == i.m_pNode;
		}
		bool operator!= (const Iterator& i)
		{
			return m_pNode != i.m_pNode;
		}
		T& operator* () const
		{
			return *Data();
		}
		T* Data() const
		{
			return m_pNode?(T*)m_pNode->Data():0;
		}
		bool IsVaild() const
		{
			return m_pNode!=0;
		}
		bool IsNewObj()
		{
			return m_pNode ? m_pNode->IsUsed()==2 : false;
		}
	private:
		typename ssDoublyList<sizeof(T)>::Node_s* m_pNode;
	};

	ssList(void)
	{
	}
	ssList(const ssList &cc)
	{
		CopyFrom(cc);
	}
	~ssList(void)
	{
		Clear();
	}
	void operator = (const ssList &cc)
	{
		CopyFrom(cc);
	}

	//从另一个容器复制
	void CopyFrom(const ssList &cc)
	{
		Empty();
		Iterator otherNode = cc.Begin();
		while (otherNode.IsVaild())
		{
			PushBack(*otherNode.Data());
			++otherNode;
		}
	}
	//增加一个数据单元
	bool PushBack(const T & t)
	{
		Iterator itr(m_list.AllotNode());
		if (itr.IsVaild())
		{
			new (itr.Data()) T(t);
			return true;
		}
		return false;
	}
	bool PushBackCP(const T t)
	{
		return PushBack(t);
	}
	//分配一个空闲的单元
	T* Allot()
	{
		Iterator& itr = AllotItr();
		return itr.Data();
	}
	Iterator AllotItr()
	{
		Iterator itr(m_list.AllotNode());
		if (itr.IsVaild())
		{
			new (itr.Data()) T();
		}
		return itr;
	}
	//移除一个数据单元,返回下一个节点
	Iterator EraseItr(Iterator& itr)
	{
		Iterator nitr;
		if (itr.IsVaild())
		{
			itr.Data()->~T();
			nitr = m_list.EraseNode(itr.m_pNode);
			itr.m_pNode = 0;
		}
		return nitr;
	}
	//必须传入链表中的对象指针才能删除
	Iterator Erase(T *pt)
	{
		Iterator nitr;
		if (pt)
		{
			pt->~T();
			nitr = m_list.Erase(pt);
		}
		return nitr;
	}
	//遍历删除相同值的节点
	bool Remove(T t)
	{
		Iterator itr = Begin();
		while (itr.IsVaild())
		{
			if (*itr.Data() == t)
			{
				EraseItr(itr);
				return true;
			}
			++itr;
		}
		return false;
	}
	//遍历删除节点，比较所有节点的值删除相同的
	ulint RemoveRepeated(T t)
	{
		ulint ret = 0;
		Iterator itr = Begin();
		while (itr.IsVaild())
		{
			if (*itr.Data()==t)
			{
				itr = EraseItr(itr);
				++ret;
			}
			else
			{
				++itr;
			}
		}
		return ret;
	}
	//清除所有节点
	void Empty()
	{
		Iterator itr = m_list.Begin();
		while (itr.IsVaild())
		{
			itr.Data()->~T();
			++itr;
		}
		m_list.Empty();
	}
	//获取有效节点头
	Iterator Begin()const {return m_list.Begin();}
	//获取有效节点尾
	Iterator Tail()const { return m_list.End(); }
	//删除第一个节点,可返回删除节点的值
	bool PopFront(T* pOut=0)
	{
		typename ssDoublyList<sizeof(T)>::Node_s* pNode = m_list.Begin();
		if (pNode)
		{
			if (pOut)
			{
				*pOut = *((T*)pNode->Data());
			}
			m_list.EraseNode(pNode);
			return true;
		}
		return false;
	}
	//删除最后一个节点,可返回删除节点的值
	bool PopTail(T* pOut = 0)
	{
		typename ssDoublyList<sizeof(T)>::Node_s* pNode = m_list.End();
		if (pNode)
		{
			if (pOut)
			{
				*pOut = *((T*)pNode->Data());
			}
			m_list.EraseNode(pNode);
			return true;
		}
		return false;
	}
	//获取链表结束
	Iterator End()const {return 0;}
	//获取有效节点数
	ulint Size()const { return m_list.UsedCount(); }
	ulint Count()const { return m_list.UsedCount(); }
	//获取节点总数
	ulint Total()const {return m_list.Total();}
	//释放无效节点内存
	void Release() { m_list.ReleaseFreeNode(); }
	//释放所有内存
	void Clear()
	{
		Iterator itr = m_list.Begin();
		while (itr.IsVaild())
		{
			itr.Data()->~T();
			++itr;
		}
		m_list.Clear();
	}

private:
	ssDoublyList<sizeof(T)>		m_list;
};

}
#endif
